package mango.orm.connect;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

import mango.Mango;

public class _Connection implements InvocationHandler {
    private static final int REACTIVE_PEROID =300000;
    private Connection conn = null;
    private boolean inUse;
    private long lastAccessTime = System.currentTimeMillis();

    public _Connection(Connection conn, boolean inUse) {
        this.conn = conn;
        this.inUse = inUse;
    }

    public boolean isInUse() {
        return inUse;
    }

    public void setInUse(boolean inUse) {
        this.inUse = inUse;
    }

    public long getLastAccessTime() {
        return lastAccessTime;
    }
    
    public void close() throws SQLException {
        if(this.conn != null) {
            this.conn.close();
        }
    }

    public Connection getConnection() {
        return (Connection) Proxy.newProxyInstance(conn.getClass().getClassLoader(), new Class<?>[]{Connection.class}, this);
    }

    public Object invoke(Object arg0, Method md, Object[] arg2) throws Throwable {
        Object obj = null;
        if ("close".equals(md.getName())) {
            this.setInUse(false);
            if(!this.conn.getAutoCommit()){
                this.conn.commit();
            }
        }
        else {
            obj = md.invoke(conn, arg2);
            this.lastAccessTime = System.currentTimeMillis();
        }
        return obj;
    }

    public void reactive(String testsql) {
        if(System.currentTimeMillis() - this.lastAccessTime >= REACTIVE_PEROID) {
            try {
                Statement stmt = conn.createStatement();
                ResultSet rs = stmt.executeQuery(testsql);
                rs.close();
                stmt.close();
                this.lastAccessTime = System.currentTimeMillis();
            } catch (Exception e) {
                try {
                    this.close();
                }
                catch (SQLException e1) {
                }
                Mango.getLog().error("db connection reactive error!!", e);
            }
        }
    }

    public boolean isClosed() {
        if(this.conn == null) {
            return true;
        }
        try {
            if(this.conn.isClosed()) {
                return true;
            }
        }
        catch (SQLException e) {
            return true;
        }
        return false;
    }
}
